package scala.afei.drum
import android.os.Handler
import scala.io.Source
import android.text.TextUtils
import android.os.Message
import android.content.res.AssetManager
import android.content.Context
import java.io.InputStream

/**
 * 根据 谱子信息来计算时间信息。
 * 主要有：
 * 每分钟拍子数，mBeatPerMinute
 * 如果不是规范的拍子，比如半拍或1/3拍，或是两拍时间有三拍，就用｛｝包起来，
 * 一个代表一拍时间，如果两拍时间有三个点就{{1 1 1}},几个括号就为占用几拍时间
 *
 * 鼓点表示，每一位代表一种鼓。最高位到最低分别为：
 * crash，tom1，tom2，tom3，ride，kick，snare，hihat
 */
class Puzi(mContext : Context, mHandler: Handler, mPuziPath: String) extends Thread {
  var mBeatPerMinute: Int = -1;
  var mTimemillionsPerBeat: Double = -1;
  var mBeatList: List[Beat] = Nil;

  init();
  
  override def run() = {
      st();
    }

  def init(): Unit = {
    
    val assetM : AssetManager = mContext.getAssets();
    val is = assetM.open("demo_beat");
    
    var time: Long = 0;
    if (!TextUtils.isEmpty(mPuziPath)) {
      
      for (line <- Source.fromInputStream(is).getLines()) {
        if (line.startsWith("BPM")) {
          mBeatPerMinute = line.split(" ")(1).toInt;
          mTimemillionsPerBeat = 60 * 1000 / mBeatPerMinute;
          println("BPM = " + mBeatPerMinute + " timePerBeat = " + mTimemillionsPerBeat);
        } else if (!line.startsWith("#")) {
          if (!TextUtils.isEmpty(line.trim)) {
            for (fragment <- line.split(" ")) {
              if (!fragment.startsWith("{")) {
                // 直接加入就ok
                mBeatList = new Beat(time, fragment.toInt) :: mBeatList;
                time += mTimemillionsPerBeat.toLong;
              } else {
                // 特殊拍子时间，一个是拍子数，一个是beat数，相除就是每beat时间
                var paiziNum: Int = {
                  var num: Int = 0;
                  for (ch <- fragment.toCharArray() if (ch == '{')) {
                    num = num + 1;
                  }
                  num;
                };
                println("paiziNum = " + paiziNum);
                var beats: Array[String] = fragment.substring(paiziNum, fragment.length() - paiziNum).trim().split("_");
                var deltaTime = paiziNum * mTimemillionsPerBeat / beats.length;
                for (beat <- beats) {
                  mBeatList = new Beat(time, beat.toInt) :: mBeatList;
                  time += deltaTime.toLong;
                }
              }
            }
          }
        }
      }
    }
  }

  def st(): Unit = {
    mBeatList = mBeatList.reverse;
    while (true) {
      for (beat <- mBeatList) {
        var msg = new Message();
        msg.what = DrumPlayActivity.WHAT_CREATE_BALL;
        msg.arg1 = beat.mDrums;
        mHandler.sendMessageDelayed(msg, beat.mTime);
      }
      
      Thread.sleep(mBeatList.last.mTime + 2000);
    }
  }

  class Beat(timeMillion: Long, drums: Int) {
    val mTime = timeMillion;
    val mDrums = drums;
  }
}